// BRDFDialog.cpp : implementation file
//

#include "../stdafx.h"
#include "../Reflectometry.h"
#include "BRDFDialog.h"
#include "afxdialogex.h"
#include "../3rdparty/CvvImage.h"

#include "../MainFrm.h"
#include "../ReflectometryDoc.h"
#include "../camera/Camera.h"

#include "ObjectDialog.h"
#include "BRDFInfoDialog.h"

// CBRDFDialog dialog

IMPLEMENT_DYNAMIC(CBRDFDialog, CDialogEx)

CBRDFDialog::CBRDFDialog(CWnd* pParent /*=NULL*/)
	: CDialogEx(CBRDFDialog::IDD, pParent)
	, m_sampleX(0)
	, m_sampleY(0)
{
	m_curImageIndex = -1;
}

CBRDFDialog::~CBRDFDialog()
{
}

void CBRDFDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CBRDFDialog, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON_LOAD_BRDF_IMAGE, &CBRDFDialog::OnBnClickedButtonLoadBrdfImage)
	ON_BN_CLICKED(IDC_BUTTON_SAVE_FEATURE, &CBRDFDialog::OnBnClickedButtonSaveFeature)
	ON_BN_CLICKED(IDC_BUTTON_COMPUTE_EXTRINSIC_PARAS, &CBRDFDialog::OnBnClickedButtonComputeExtrinsicParas)
	ON_BN_CLICKED(IDC_BUTTON_COMPUTE_BRDF, &CBRDFDialog::OnBnClickedButtonComputeBrdf)
	ON_BN_CLICKED(IDC_BUTTON_EVALUATION, &CBRDFDialog::OnBnClickedButtonEvaluation)
	ON_WM_LBUTTONDOWN()
	ON_BN_CLICKED(IDC_BUTTON_TEST_EXTRINSIC, &CBRDFDialog::OnBnClickedButtonTestExtrinsic)
END_MESSAGE_MAP()


// CBRDFDialog message handlers

void CBRDFDialog::ShowImage(IplImage* pImage, UINT ID)
{
	CDC *pDC = GetDlgItem(ID)->GetDC();
	HDC hDC= pDC->GetSafeHdc();
	CRect rect;
	GetDlgItem(ID)->GetClientRect(&rect);
	CvvImage cimg;
	cimg.CopyOf(pImage);
	cimg.DrawToHDC(hDC, &rect);
	ReleaseDC(pDC);
}

void CBRDFDialog::OnBnClickedButtonLoadBrdfImage()
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
	CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
	CCamera *pCamera = pDoc->GetCamera();

	if (m_curImageIndex < pCamera->GetBRDFPhotoCount() - 1)
		m_curImageIndex++;
	else
	{
		//	message box
		MessageBox(_T("it is the last image!"), _T("WARNING"), MB_OK|MB_ICONWARNING);
		m_curImageIndex = -1;
		return;
	}
	CBRDFPhoto photo = pCamera->GetBRDFPhoto(m_curImageIndex);
	ShowImage(photo.GetImage(), IDC_STATIC_GROUNDTRUTH);
 	if (!photo.LoadFeaturesFromFile())
		pCamera->InitSampleFromBRDFPhoto(m_curImageIndex);
}


void CBRDFDialog::OnBnClickedButtonSaveFeature()
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
	CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
	CCamera *pCamera = pDoc->GetCamera();

	int n = pCamera->GetBRDFPhotoCount();
	for (int i = 0; i < n; i++)
	{
		pCamera->GetBRDFPhoto(i).SaveFeaturesIntoFile();
	}
}


void CBRDFDialog::OnBnClickedButtonComputeExtrinsicParas()
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
	CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
	CCamera *pCamera = pDoc->GetCamera();

	pCamera->CalcBRDFPhotoParas(m_curImageIndex);
}


void CBRDFDialog::OnBnClickedButtonComputeBrdf()
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
	CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
	CCamera *pCamera = pDoc->GetCamera();

	CBRDFInfoDialog brdfInfoDlg;
	if (brdfInfoDlg.DoModal() == IDOK)
	{
		pCamera->CalcBRDF(brdfInfoDlg.GetSamples(), 
			brdfInfoDlg.GetXRes(), brdfInfoDlg.GetYRes(),
			brdfInfoDlg.GetXSize(), brdfInfoDlg.GetYSize(),
			brdfInfoDlg.GetNeighbour());
	}
}


void CBRDFDialog::OnBnClickedButtonEvaluation()
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
	CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
	CCamera *pCamera = pDoc->GetCamera();

	CBRDFPhoto photo = pCamera->EvalBRDF(m_curImageIndex);
	ShowImage(photo.GetImage(), IDC_STATIC_EVALUATE);
}


void CBRDFDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	CRect rect;
	this->GetDlgItem(IDC_STATIC_GROUNDTRUTH)->GetWindowRect(&rect);
	ScreenToClient(rect);
	point.x -= rect.left;
	point.y -= rect.top;

	CObjectDialog objDlg;
	float ox, oy, oz;
	
	if (objDlg.DoModal() == IDOK)
	{
		ox = objDlg.GetObjectX();
		oy = objDlg.GetObjectY();
		oz = objDlg.GetObjectZ();

		CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
		CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
		CCamera *pCamera = pDoc->GetCamera();

		CBRDFPhoto photo = pCamera->GetBRDFPhoto(m_curImageIndex);

		float ix, iy;
		ix = photo.GetWidth() * (float)point.x / (rect.right - rect.left);
		iy = photo.GetHeight() * (float)point.y / (rect.bottom - rect.top);
		pCamera->SampleFromBRDFPhoto(m_curImageIndex, ox, oy, oz, ix, iy);
	}

	CDialogEx::OnLButtonDown(nFlags, point);
}


void CBRDFDialog::OnBnClickedButtonTestExtrinsic()
{
	// TODO: Add your control notification handler code here
	CPoint3D point;
	CObjectDialog objDlg;
	if (objDlg.DoModal() == IDOK)
	{
		point.m_x = objDlg.GetObjectX();
		point.m_y = objDlg.GetObjectY();
		point.m_z = objDlg.GetObjectZ();

		CPixel pixel;
		CMainFrame* pMainFrame = (CMainFrame *)AfxGetMainWnd();
		CReflectometryDoc *pDoc = (CReflectometryDoc *)pMainFrame->GetActiveDocument();
		CCamera *pCamera = pDoc->GetCamera();

		CBRDFPhoto photo = pCamera->GetBRDFPhoto(m_curImageIndex);
		photo.GlobalPoint3D2Pixel(point, pixel);
		int height = photo.GetHeight();
		int width = photo.GetWidth();
		for (int i = 0; i < height; i++)
			photo.SetPixelColor(pixel.m_x, i, 255, 0, 0);
		for (int i = 0; i < width; i++)
			photo.SetPixelColor(i, pixel.m_y, 255, 0, 0);

		ShowImage(photo.GetImage(), IDC_STATIC_GROUNDTRUTH);
	}
}
